/*   LPT Leds Visualization Plugin for Audacious
 *   based on xplsisnjasp XMMS plugin http://www.na.linux.hr/projects/xplsisnjasp/
 *  
 *  Copyright (C) 2009 Aleksey Makchno <silentlexx@gmail.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include <gtk/gtk.h>
#include <audacious/plugin.h>
#include <audacious/configdb.h>


#include "xpl.xpm"

/*
#include <sys/io.h>
#define base 0x378   
*/

#define OUTPUT		0


#define VERSION		"0.3"

#define NUM_BANDS            8
#define DEFAULTSENSE         10
#define MAX_SENSE            50


#define D0	1 
#define D1	2
#define D2	4
#define D3	8
#define D4	16
#define D5	32
#define D6	64
#define D7	128

#define WIDTH 275
#define HEIGHT 116


typedef struct
{
	gboolean myconfig;
/*
	gint lptadr;
	*/
	gboolean draw_gfx;
        gint chsense[NUM_BANDS];
	/*gboolean tousefirst;*/
	gboolean VUmode;
	gboolean VUlr;
	/* stepper motor stuff */
	gboolean use_stepper; /* to use stepper motor [0]*/
	gint band_start; /* where the stepper stops and the band begins
			if you don't have a stepper, set this to 0 [0] */
	gint num_steps;	/* [4] */
	gint step_interval; /* this is for the stepper speed control. 
				lower is faster and 0 is the fastest
				(no delay) [3]*/
} LptConfig;

static LptConfig lcfg,locfg;

static gint16 bar_heights[NUM_BANDS];
static gdouble scale;
static gint pstep = 0; /* counter so the stepper doesn't go too fast */
static gint curstep = 0;
//static gboolean send_ok = FALSE;
static gint oldmoveall = DEFAULTSENSE;
static gint timeout_tag;
static GtkWidget *window = (GtkWidget *)NULL;
static GtkWidget *area = (GtkWidget *)NULL;
static GdkPixmap *bg_pixmap = (GdkPixmap *)NULL;
static GdkPixmap *draw_pixmap = (GdkPixmap *)NULL;
static GdkPixmap *bar = (GdkPixmap *)NULL;
static GdkGC *gc = (GdkGC *)NULL;
static gboolean playing = FALSE;

static void init(void);
static void cleanup(void);
static void about(void);
static void configure(void);
static void playback_start(void);
static void playback_stop(void);
static void render_freq(gint16 data[2][256]);

static void portb(gint data);

/* Configure part of parport */
static GtkWidget *configure_win = (GtkWidget *)NULL;
static GtkWidget *vbox = (GtkWidget *)NULL;
static GtkWidget *options_frame = (GtkWidget *)NULL;
static GtkWidget *options_vbox = (GtkWidget *)NULL;
static GtkWidget *bbox = (GtkWidget *)NULL;
static GtkWidget *ok = (GtkWidget *)NULL;
static GtkWidget *cancel = (GtkWidget *)NULL;
static GtkWidget *notebook1 = (GtkWidget *)NULL;
static GtkWidget *gvbox = (GtkWidget *)NULL;
static GtkWidget *generallabel = (GtkWidget *)NULL;
static GtkWidget *myconfig = (GtkWidget *)NULL;
static GtkWidget *hbox = (GtkWidget *)NULL;
static GtkWidget *lpt_address_label = (GtkWidget *)NULL;
static GtkWidget *lpt_address = (GtkWidget *)NULL;
static GtkWidget *draw_gfx = (GtkWidget *)NULL;
static GtkWidget *VUmode = (GtkWidget *)NULL;
static GtkWidget *VUlr = (GtkWidget *)NULL;
static GtkWidget *use_stepper = (GtkWidget *)NULL;
static GtkWidget *chanells_frame = (GtkWidget *)NULL;
static GtkWidget *chanells_vbox = (GtkWidget *)NULL;
static GtkWidget *svbox = (GtkWidget *)NULL;
static GtkWidget *senselabel = (GtkWidget *)NULL;
static GtkWidget *pansep_hscale[NUM_BANDS] = { (GtkWidget *)NULL };
static GtkWidget *pansep_adj[NUM_BANDS] = { (GtkWidget *)NULL };
static GtkWidget *panhbox[NUM_BANDS] = { (GtkWidget *)NULL };
static GtkWidget *panlabel[NUM_BANDS] = { (GtkWidget *)NULL };
static GtkWidget *lock_frame = (GtkWidget *)NULL;
static GtkWidget *lock_vbox = (GtkWidget *)NULL;
/* static GtkWidget *tousefirst = (GtkWidget *)NULL; */
static GtkWidget *lockchan = (GtkWidget *)NULL;
static GtkWidget *lockscale = (GtkWidget *)NULL;



VisPlugin lptleds_vp = {
	.description = "LPT Leds",
	.num_pcm_chs_wanted = 0,
	.num_freq_chs_wanted = 1,
	.init = init, /* init */
	.cleanup = cleanup, /* cleanup */
	.about = about,
	.configure = configure,
	.playback_start = playback_start, /* playback_start */
	.playback_stop = playback_stop, /* playback_stop */
	.render_freq = render_freq  /* render_freq */
};

VisPlugin *lptleds_vplist[] = { &lptleds_vp, NULL };

DECLARE_PLUGIN(lptleds, NULL, NULL, NULL, NULL, NULL, NULL, lptleds_vplist,NULL);


static void portb(gint data) {

/*
ioperm(base,1,1);
outb(data,base);
usleep(100);
ioperm(base,1,0);
*/

char buffer[10];
sprintf(buffer, "lptout %i", data);
system(buffer);

}


static void playback_start_internal(void)
{
	if (!lcfg.draw_gfx)
		return;
	if (!playing)
		return;
if (lcfg.draw_gfx)
{
	if (window != (GtkWidget *)NULL)
	{
		gdk_window_set_back_pixmap(area->window, draw_pixmap, 0);
		gdk_window_clear(area->window);
	}
}
}


static void playback_stop_internal(void)
{
	if (!playing)
		return;
if (lcfg.draw_gfx)
{
	if (GTK_WIDGET_REALIZED(area))
	{
		gdk_window_set_back_pixmap(area->window, bg_pixmap, 0);
		gdk_window_clear(area->window);
	}
}
		
}


static void init(void) {
gint ii,i,tmp;
GdkColor color;

mcs_handle_t *cf;

//   DEBUG("alarm_save\n");


scale = HEIGHT / log(256);



   cf = aud_cfg_db_open();


  		if(!aud_cfg_db_get_bool(cf, "lptleds", "myconfig",&lcfg.myconfig))
		  lcfg.myconfig = FALSE;
		if(!aud_cfg_db_get_bool(cf, "lptleds", "draw_gfx",&lcfg.draw_gfx))
		  lcfg.draw_gfx = FALSE;
		if(!aud_cfg_db_get_bool(cf, "lptleds", "vumode", &lcfg.VUmode)) 	
		lcfg.VUmode = FALSE;
		if(!aud_cfg_db_get_bool(cf, "lptleds", "vulr", &lcfg.VUlr))
		 lcfg.VUlr = TRUE;
		//if(!aud_cfg_db_get_int(cf, "lptleds", "lptadr", &lcfg.lptadr))		 ;
		if(!aud_cfg_db_get_bool(cf, "lptleds", "use_stepper", &lcfg.use_stepper))
		 lcfg.use_stepper = FALSE;
		if(!aud_cfg_db_get_int(cf, "lptleds", "band_start", &lcfg.band_start))
		 lcfg.band_start = 0;
		if(!aud_cfg_db_get_int(cf, "lptleds", "num_steps", &lcfg.num_steps))
		 lcfg.num_steps = 4;
		if(!aud_cfg_db_get_int(cf, "lptleds", "step_interval", &lcfg.step_interval))
		 lcfg.step_interval = 3; 
		

		for (ii = 0; ii < NUM_BANDS; ii++)
		{
			gchar chsensetext[20];
			sprintf(chsensetext, "chsense%d", ii);
			if(!aud_cfg_db_get_int(cf, "lptleds", chsensetext,&lcfg.chsense[ii]))
			 lcfg.chsense[ii] = DEFAULTSENSE;
		}
		
		aud_cfg_db_close(cf);

portb(0);


/* GFX */
if (lcfg.draw_gfx)
{
	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_window_set_title(GTK_WINDOW(window), "LEDLPT Show");
	gtk_window_set_policy(GTK_WINDOW(window), FALSE, FALSE, FALSE);
	gtk_widget_realize(window);
	bg_pixmap = gdk_pixmap_create_from_xpm_d(window->window, NULL, NULL,
		xpl_xpm);
	gdk_window_set_back_pixmap(window->window, bg_pixmap, 0);
	//gtk_signal_connect_object(GTK_OBJECT(window), "destroy",
	//	GTK_SIGNAL_FUNC(parport_destroy_cb), NULL);
	gtk_signal_connect(GTK_OBJECT(window), "destroy",
		GTK_SIGNAL_FUNC(gtk_widget_destroyed), &window);
	gtk_widget_set_usize(window, WIDTH, HEIGHT);
	gc = gdk_gc_new(window->window);
	draw_pixmap = gdk_pixmap_new(window->window, WIDTH, HEIGHT,
		gdk_visual_get_best_depth());
	bar = gdk_pixmap_new(window->window, 25, HEIGHT,
		gdk_visual_get_best_depth());




		for (i = 0; i < HEIGHT / 2; i++)
		{
			color.red = 0xFFFF;
			/* color.green = ((i * 255) / (HEIGHT / 2)) << 8; */
			color.green = 0;
			color.blue = 0;
			gdk_color_alloc(gdk_colormap_get_system(), &color);
			gdk_gc_set_foreground(gc, &color);
			gdk_draw_line(bar, gc, 0, i, 24, i);
		}


	for(i = 0; i < HEIGHT / 2; i++)
	{
		/* color.red = (255 - ((i * 255) / (HEIGHT / 2))) << 8; */
		color.red = 0xAAAA;
		color.green = 0xAAAA;
		color.blue = 0xAAAA;
		gdk_color_alloc(gdk_colormap_get_system(), &color);
		gdk_gc_set_foreground(gc, &color);
		gdk_draw_line(bar, gc, 0, i + (HEIGHT / 2), 24,
			i + (HEIGHT / 2));
	}
	scale = HEIGHT / log(256);
	gdk_color_black(gdk_colormap_get_system(), &color);
	gdk_gc_set_foreground(gc, &color);
	area = gtk_drawing_area_new();
	gtk_container_add(GTK_CONTAINER(window), area);
	gtk_widget_realize(area);
	gdk_window_set_back_pixmap(area->window, bg_pixmap, 0);
	gtk_widget_show(area);
	gtk_widget_show(window);
	gdk_window_clear(window->window);
	gdk_window_clear(area->window);
}
}

static void cleanup(void) {
portb(0);
	if (!playing)
		return;
if (lcfg.draw_gfx)
{

	if (gc != (GdkGC *)NULL)
	{
		gdk_gc_unref(gc);
		gc = (GdkGC *)NULL;
	}
	if (bg_pixmap != (GdkPixmap *)NULL)
	{
		gdk_pixmap_unref(bg_pixmap);
		bg_pixmap = (GdkPixmap *)NULL;
	}
	if (draw_pixmap != (GdkPixmap *)NULL)
	{
		gdk_pixmap_unref(draw_pixmap);
		draw_pixmap = (GdkPixmap *)NULL;
	}
	if (bar != (GdkPixmap *)NULL)
	{
		gdk_pixmap_unref(bar);
		bar = (GdkPixmap *)NULL;
	}
	if (window != (GtkWidget *)NULL)
	{
		gtk_widget_destroy(window);
		window = (GtkWidget *)NULL;
	}
}
	playing = FALSE;

}

static void playback_start(void) {
portb(0);
if (playing)
	return;
playing = TRUE;
playback_start_internal();
}

static void playback_stop(void) {
portb(0);
	if (!playing)
		return;
	playback_stop_internal();
	playing = FALSE;
}

static gboolean draw_func(gpointer data) {

	 gint i, lptdata;
	 gint *conditions;
	 gint con1[8] = { D0, D1, D2, D3, D4, D5, D6, D7 }; // Liner 1,2,3... 
         gint con2[8] = { D2, D3, D1, D4, D0, D5, D7, D6 }; // My for circle

 if (!lcfg.myconfig)
 {
	//memcpy(&conditions, &con1, sizeof(con1));
        conditions = &con1[0];
 }
 else 
 {
	//memcpy(&conditions, &con2, sizeof(con2));
	conditions = &con2[0];
 }

	if (lcfg.draw_gfx)
	{
	if (window == NULL)
	{
		timeout_tag = 0;
		return FALSE;
	}

		GDK_THREADS_ENTER();
		gdk_draw_rectangle(draw_pixmap, gc, TRUE, 0, 0, WIDTH, HEIGHT);
	}
        lptdata = 0;
	for (i = 0; i < NUM_BANDS; i++)
	{
		//bar_heights[i] -= BARDEC;
		if (lcfg.use_stepper)
		{
			bar_heights[i] -= 4;
		}
		else
		{
			bar_heights[i] -= 50;
		}

		if (bar_heights[i] < 0)
			bar_heights[i] = 0;
		if (bar_heights[i] > lcfg.chsense[i])
		{
			if (lcfg.use_stepper)
			{
				lptdata += conditions[i + lcfg.band_start];
			}
			else
			{
				lptdata += conditions[i];
			}
			if (lcfg.draw_gfx)
			{

			/*	gdk_draw_pixmap(draw_pixmap, gc, bar, 0, 0,
					i * (WIDTH / NUM_BANDS), 0,
					(WIDTH / NUM_BANDS) - 1, HEIGHT - 1); */
					gdk_draw_pixmap(draw_pixmap, gc, bar, 0,
					HEIGHT - 1 - bar_heights[i],
					i * (WIDTH / NUM_BANDS),
					HEIGHT - 1 - bar_heights[i],
					(WIDTH / NUM_BANDS) - 1,
					bar_heights[i]);

			}
		}
	}

		if (lcfg.use_stepper)
		{
			if (!pstep) 
			{
				lptdata += pow(2,curstep);
				curstep++;
				curstep %= lcfg.num_steps;
			}
			pstep++;
			pstep %= lcfg.step_interval;
		} 

// DEBUG
if (OUTPUT) {
printf("%i - %i - %i - %i - %i - %i - %i - %i --- %i\n",bar_heights[0],bar_heights[1],bar_heights[2],bar_heights[3],bar_heights[4],bar_heights[5],bar_heights[6],bar_heights[7],lptdata);
}



if (lptdata > -1 && lptdata < 256) portb(lptdata);

	if (lcfg.draw_gfx)
	{
		gdk_window_clear(area->window);
		GDK_THREADS_LEAVE();
	}

return TRUE;
}



static void render_freq(gint16 data[2][256]) {
	gint i, c, y;
	gint xscale[] =
	{
		0, 1, 2, 3, 5, 7, 10, 14, 20, 28, 40, 54,
		74, 101, 137, 187, 255
	};

if (lcfg.VUmode)
{
	gint tmp = 0;
	for (i = 0; i < 256; i++)
	{
	//gint d = (data[0][i] + data[1][i]) >> 1;  // MIX ?
		gint d = data[0][i];
		tmp += d;
		}
		tmp /= 256;
		tmp /= 70;
		if (tmp < 0)
			tmp = 0;
		if (tmp > 8)
			tmp = 8;
		for (i = 0; i < tmp; i++)
			bar_heights[lcfg.VUlr ? i : 7 - i] = 101;
		for (i = tmp; i < 8; i++)
			bar_heights[lcfg.VUlr ? i : 7 - i] = 0;
	}
	else
	{
	for (i = 0; i < NUM_BANDS; i++)
	{
		for (c = xscale[i], y = 0; c < xscale[i + 1]; c++)
		{
//			gint d = (data[0][c] + data[1][c]) >> 1; // MIX ?
		  gint d = data[0][c];
			if (d > y)
					y = d;
			}
			y >>= 7;
			if (y != 0)
			{
				y = (gint)(log(y) * scale);
				if (y > HEIGHT - 1)
					y = HEIGHT - 1;
			}
			if (y > bar_heights[i])
				bar_heights[i] = y;
			else
			{
			bar_heights[i] -= 4;
			if (bar_heights[i] < 0)
				bar_heights[i] = 0;
		}
	}
}

        draw_func(data);
 return;

}



static void configure_destroy(void)
{
	int i;

#if WIDGET_DESTROY
	if (vbox != NULL)
		gtk_widget_destroy(vbox);
#endif
	vbox = NULL;
#if WIDGET_DESTROY
	if (options_frame != NULL)
		gtk_widget_destroy(options_frame);
#endif
	options_frame = NULL;
#if WIDGET_DESTROY
	if (options_vbox != NULL)
		gtk_widget_destroy(options_vbox);
#endif
	options_vbox = NULL;
#if WIDGET_DESTROY
	if (bbox != NULL)
		gtk_widget_destroy(bbox);
#endif
	bbox = NULL;
#if WIDGET_DESTROY
	if (ok != NULL)
		gtk_widget_destroy(ok);
#endif
	ok = NULL;
#if WIDGET_DESTROY
	if (cancel != NULL)
		gtk_widget_destroy(cancel);
#endif
	cancel = NULL;
#if WIDGET_DESTROY
	if (notebook1 != NULL)
		gtk_widget_destroy(notebook1);
#endif
	notebook1 = NULL;
#if WIDGET_DESTROY
	if (gvbox != NULL)
		gtk_widget_destroy(gvbox);
#endif
	gvbox = NULL;
#if WIDGET_DESTROY
	if (generallabel != NULL)
		gtk_widget_destroy(generallabel);
#endif
	generallabel = NULL;
#if WIDGET_DESTROY
	if (myconfig != NULL)
		gtk_widget_destroy(myconfig);
#endif
	myconfig = NULL;
#if WIDGET_DESTROY
	if (hbox != NULL)
		gtk_widget_destroy(hbox);
#endif
	hbox = NULL;
#if WIDGET_DESTROY
	if (lpt_address_label != NULL)
		gtk_widget_destroy(lpt_address_label);
#endif
	lpt_address_label = NULL;
#if WIDGET_DESTROY
	if (lpt_address != NULL)
		gtk_widget_destroy(lpt_address);
#endif
	lpt_address = NULL;
#if WIDGET_DESTROY
	if (draw_gfx != NULL)
		gtk_widget_destroy(draw_gfx);
#endif
	draw_gfx = NULL;
#if WIDGET_DESTROY
	if (VUmode != NULL)
		gtk_widget_destroy(VUmode);
#endif
	VUmode = NULL;
#if WIDGET_DESTROY
	if (VUlr != NULL)
		gtk_widget_destroy(VUlr);
#endif
	VUlr = NULL;
#if WIDGET_DESTROY
	if (chanells_frame != NULL)
		gtk_widget_destroy(chanells_frame);
#endif
	chanells_frame = NULL;
#if WIDGET_DESTROY
	if (chanells_vbox != NULL)
		gtk_widget_destroy(chanells_vbox);
#endif
	chanells_vbox = NULL;
#if WIDGET_DESTROY
	if (svbox != NULL)
		gtk_widget_destroy(svbox);
#endif
	svbox = NULL;
#if WIDGET_DESTROY
	if (senselabel != NULL)
		gtk_widget_destroy(senselabel);
#endif
	senselabel = NULL;
	for (i = 0; i < NUM_BANDS; i++)
	{
#if WIDGET_DESTROY
		if (pansep_hscale[i] != NULL)
			gtk_widget_destroy(pansep_hscale[i]);
#endif
		pansep_hscale[i] = NULL;
#if WIDGET_DESTROY
		if (pansep_adj[i] != NULL)
			gtk_widget_destroy(pansep_adj[i]);
#endif
		pansep_adj[i] = NULL;
#if WIDGET_DESTROY
		if (panhbox[i] != NULL)
			gtk_widget_destroy(panhbox[i]);
#endif
		panhbox[i] = NULL;
#if WIDGET_DESTROY
		if (panlabel[i] != NULL)
			gtk_widget_destroy(panlabel[i]);
#endif
		panlabel[i] = NULL;
	}
#if WIDGET_DESTROY
	if (lock_frame != NULL)
		gtk_widget_destroy(lock_frame);
#endif
	lock_frame = NULL;
#if WIDGET_DESTROY
	if (lock_vbox != NULL)
		gtk_widget_destroy(lock_vbox);
#endif
	lock_vbox = NULL;
/*
#if WIDGET_DESTROY
	if (tousefirst != NULL)
		gtk_widget_destroy(tousefirst);
#endif
	tousefirst = NULL;
*/
#if WIDGET_DESTROY
	if (lockchan != NULL)
		gtk_widget_destroy(lockchan);
#endif
	lockchan = NULL;
#if WIDGET_DESTROY
	if (lockscale != NULL)
		gtk_widget_destroy(lockscale);
#endif
	lockscale = NULL;
	if (configure_win != NULL)
		gtk_widget_destroy(configure_win);
	configure_win = NULL;
}

  
static void conf_moveall(GtkWidget *w, gpointer data)
{
	gint ii, nvalue, now, diff;
	now = GTK_ADJUSTMENT(lockchan)->value;
	diff = (now - oldmoveall);
	if (diff != 0)
	{
		for (ii = 0; ii < NUM_BANDS; ii++)
		{
			nvalue = GTK_ADJUSTMENT(pansep_adj[ii])->value;
			nvalue += diff;
			if (nvalue < 1)
				nvalue = 1;
			if (nvalue > MAX_SENSE)
				nvalue = MAX_SENSE;
			gtk_adjustment_set_value(GTK_ADJUSTMENT(pansep_adj[ii]), nvalue);
		}
	}
	oldmoveall = GTK_ADJUSTMENT(lockchan)->value;
}


static void conf_apply(GtkWidget *w, gpointer data)
{
	if (w == NULL)
		return;
	if (myconfig != NULL && w == myconfig)
	{
		lcfg.myconfig = gtk_toggle_button_get_active(
			GTK_TOGGLE_BUTTON(myconfig));
		if (lpt_address_label != NULL)
		{
			gtk_widget_set_sensitive(lpt_address_label,
				lcfg.myconfig);
		}
		if (lpt_address != NULL)
			gtk_widget_set_sensitive(lpt_address, lcfg.myconfig);
	}
/*	else if (lpt_address != NULL && w == lpt_address)
	{
		gchar *tempadr = gtk_entry_get_text(GTK_ENTRY(lpt_address));
		sscanf(tempadr, "%i", &cfg.lptadr);
	}
	else if (draw_gfx != NULL && w == draw_gfx)
	{
		gboolean ok = send_ok;
		cfg.draw_gfx = gtk_toggle_button_get_active(
			GTK_TOGGLE_BUTTON(draw_gfx));
		send_ok = FALSE;
		if (lcfg.draw_gfx)
			parport_playback_start_internal();
		else
			parport_playback_stop_internal();
		send_ok = ok;

#if 0
		if (VUmode != NULL)
			gtk_widget_set_sensitive(VUmode, cfg.draw_gfx);
		if (VUlr != NULL)
		{
			gtk_widget_set_sensitive(VUlr,
				cfg.draw_gfx && cfg.VUmode);
		}
#endif

	}
 */
	else if (draw_gfx != NULL && w == draw_gfx)
	{
		//gboolean ok = send_ok;
		lcfg.draw_gfx = gtk_toggle_button_get_active(
			GTK_TOGGLE_BUTTON(draw_gfx));
		//send_ok = FALSE;
		if (lcfg.draw_gfx)
			playback_start_internal();
		else
			playback_stop_internal();
		//send_ok = ok;
	}
        else if (VUmode != NULL && w == VUmode)
	{
		lcfg.VUmode = gtk_toggle_button_get_active(
			GTK_TOGGLE_BUTTON(VUmode));
		if (VUlr != NULL)
			gtk_widget_set_sensitive(VUlr, lcfg.VUmode);
	}
	else if (VUlr != NULL && w == VUlr)
	{
		lcfg.VUlr = !gtk_toggle_button_get_active(
			GTK_TOGGLE_BUTTON(VUlr));
	}
	else
	{
		int i;
		for (i = 0; i < NUM_BANDS; i++)
		{
			if (pansep_adj[i] != NULL && w == pansep_adj[i])
			{
				lcfg.chsense[i] =
					GTK_ADJUSTMENT(pansep_adj[i])->value;
				break;
			}
		}
	}
}


static void conf_ok(GtkWidget *w, gpointer data)
{
   mcs_handle_t *cf;

//   DEBUG("alarm_save\n");

   cf = aud_cfg_db_open();


	//ConfigFile *cf;
/*
#if 0
	gchar *filename;
#endif
*/
//	gchar *tempadr;
	gint ii;
//	tempadr = gtk_entry_get_text(GTK_ENTRY(lpt_address));
/*	sscanf(tempadr, "%i", &cfg.lptadr); */
	lcfg.myconfig = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(myconfig));
	lcfg.draw_gfx =
		gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(draw_gfx));
	lcfg.VUmode =
		gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(VUmode));
	lcfg.VUlr =
		!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(VUlr));
	lcfg.use_stepper =
		gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(use_stepper));
/*	lcfg.band_start =
		gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(band_start));
	lcfg.num_steps =
		gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(num_steps));
	lcfg.step_interval =
		gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(step_interval));

/*
	cfg.tousefirst =
		gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tousefirst));
	if (cfg.tousefirst)
	{
		for (ii = 0; ii < NUM_BANDS; ii++)
			cfg.chsense[ii] = GTK_ADJUSTMENT(pansep_adj[0])->value;
	}
	else
*/
	{
		gint tmp = 0;
		for (ii = 0; ii < NUM_BANDS; ii++)
		{
			lcfg.chsense[ii] = GTK_ADJUSTMENT(pansep_adj[ii])->value;
			tmp += lcfg.chsense[ii];
		}
		oldmoveall = (tmp / NUM_BANDS);
	}
/*#if 0
	filename = g_strconcat(g_get_home_dir(), "/.xmms/config", NULL);
	cf = xmms_cfg_open_file(filename);
	if (cf == (ConfigFile *)NULL)
		cf = xmms_cfg_new();
#else

	cf = xmms_cfg_open_default_file();
#endif

	aud_cfg_db_set_int(cf, "lptleds", "lptadr", cfg.lptadr);
	*/

	aud_cfg_db_set_bool(cf, "lptleds", "myconfig", lcfg.myconfig);
	aud_cfg_db_set_bool(cf, "lptleds", "draw_gfx", lcfg.draw_gfx);
	aud_cfg_db_set_bool(cf,"lptleds","vumode", lcfg.VUmode);
	aud_cfg_db_set_bool(cf,"lptleds","vulr", lcfg.VUlr);
	aud_cfg_db_set_bool(cf,"lptleds","use_stepper", lcfg.use_stepper);
	aud_cfg_db_set_int (cf,"lptleds","band_start", lcfg.band_start);
	aud_cfg_db_set_int (cf,"lptleds","num_steps", lcfg.num_steps);
	aud_cfg_db_set_int (cf,"lptleds","step_interval", lcfg.step_interval);
	for (ii = 0; ii < NUM_BANDS; ii++)
	{
		gchar chsensetext[20];
		sprintf(chsensetext,"chsense%d", ii);
		aud_cfg_db_set_int(cf,"lptleds",chsensetext,lcfg.chsense[ii]);
	}

	
        aud_cfg_db_close(cf);



	configure_destroy();


/*
#if 0
	aud_cfg_db_set_file(cf, filename);
#else
	aud_cfg_db_set_default_file(cf);
#endif
	xmms_cfg_free(cf);
#if 0
	g_free(filename);
#endif
	configure_destroy();
*/

}


static void conf_cancel(GtkWidget *w, gpointer data)
{
	memcpy(&lcfg, &locfg, sizeof(lcfg));
	configure_destroy();
}




static void configure(void) {
	gint ii;
	char mytext[10];
	if (configure_win != (GtkWidget *)NULL)
		return;
	//read_config();
	memcpy(&locfg, &lcfg, sizeof(locfg));
	configure_win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_container_set_border_width(GTK_CONTAINER(configure_win), 10);
	gtk_window_set_title(GTK_WINDOW(configure_win),
		"LPTLEDS Configuration");
	gtk_window_set_policy(GTK_WINDOW(configure_win), FALSE, FALSE, FALSE);
	gtk_window_set_position(GTK_WINDOW(configure_win), GTK_WIN_POS_MOUSE);
	gtk_signal_connect(GTK_OBJECT(configure_win), "destroy",
		GTK_SIGNAL_FUNC(gtk_widget_destroyed), &configure_win);
	vbox = gtk_vbox_new(FALSE, 5);
	gvbox = gtk_vbox_new(FALSE, 5);
	notebook1 = gtk_notebook_new();
	gtk_object_set_data(GTK_OBJECT(configure_win), "notebook1",
		notebook1);
	gtk_widget_show(notebook1);
	gtk_box_pack_start(GTK_BOX(gvbox), notebook1, TRUE, TRUE, 0);
	gtk_container_border_width(GTK_CONTAINER(notebook1), 3);
	options_frame = gtk_frame_new("Options:");
	gtk_container_set_border_width(GTK_CONTAINER(options_frame), 5);
	options_vbox = gtk_vbox_new(FALSE, 5);
	gtk_container_set_border_width(GTK_CONTAINER(options_vbox), 5);
	myconfig = gtk_check_button_new_with_label(
	  "My config (Lexx)");
//	"Send data to LPT port (needs r00t)");
	gtk_signal_connect(GTK_OBJECT(myconfig), "clicked",
		GTK_SIGNAL_FUNC(conf_apply), GTK_OBJECT(configure_win));
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(myconfig),
		lcfg.myconfig);
	gtk_box_pack_start(GTK_BOX(options_vbox), myconfig,
		FALSE, FALSE, 0);
	gtk_widget_show(myconfig); 
/*
	hbox = gtk_hbox_new(FALSE, 5);
	gtk_box_pack_start(GTK_BOX(options_vbox), hbox, FALSE, FALSE, 0);
	lpt_address_label = gtk_label_new("LPT address:");
	gtk_box_pack_start(GTK_BOX(hbox), lpt_address_label, FALSE, FALSE, 0);
	gtk_widget_show(lpt_address_label);
	lpt_address = gtk_entry_new();
	if (cfg.lptadr != 0)
	{
		gchar tempadr[20];
		sprintf(tempadr, "0x%X", cfg.lptadr);
		gtk_entry_set_text(GTK_ENTRY(lpt_address), tempadr);
	}
	gtk_widget_set_usize(lpt_address, 200, -1);
	gtk_box_pack_start(GTK_BOX(hbox), lpt_address, TRUE, TRUE, 0);
	gtk_widget_show(lpt_address);
	gtk_widget_show(hbox);*/
	gtk_widget_set_sensitive(lpt_address, lcfg.myconfig);
	gtk_widget_set_sensitive(lpt_address_label, lcfg.myconfig);
	draw_gfx = gtk_check_button_new_with_label("Draw (debug) graphics");
	gtk_signal_connect(GTK_OBJECT(draw_gfx), "clicked",
		GTK_SIGNAL_FUNC(conf_apply), GTK_OBJECT(configure_win));
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(draw_gfx),
		lcfg.draw_gfx);
	gtk_box_pack_start(GTK_BOX(options_vbox), draw_gfx, FALSE, FALSE, 0);
	gtk_widget_show(draw_gfx);

	VUmode = gtk_check_button_new_with_label("VU-meter mode");
	gtk_signal_connect(GTK_OBJECT(VUmode), "clicked",
		GTK_SIGNAL_FUNC(conf_apply), GTK_OBJECT(configure_win));
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(VUmode),
		lcfg.VUmode);
	gtk_box_pack_start(GTK_BOX(options_vbox), VUmode, FALSE, FALSE, 0);
	gtk_widget_show(VUmode);
	/* gtk_widget_set_sensitive(VUmode, cfg.draw_gfx); */ 
	/* Check box for rightside VU-meter */
	VUlr = gtk_check_button_new_with_label("Rightside VU-meter");
	gtk_signal_connect(GTK_OBJECT(VUlr), "clicked",
		GTK_SIGNAL_FUNC(conf_apply), GTK_OBJECT(configure_win));
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(VUlr),
		!lcfg.VUlr);
	gtk_box_pack_start(GTK_BOX(options_vbox), VUlr, FALSE, FALSE, 0);
	gtk_widget_show(VUlr);
	gtk_widget_set_sensitive(VUlr, lcfg.VUmode);
	/* Check box for Stepper Motor */
	use_stepper = gtk_check_button_new_with_label("Stepper Motor");
	gtk_signal_connect(GTK_OBJECT(use_stepper), "clicked",
		GTK_SIGNAL_FUNC(conf_apply), GTK_OBJECT(configure_win));
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(use_stepper),
		lcfg.use_stepper);
	gtk_box_pack_start(GTK_BOX(options_vbox), use_stepper, FALSE, FALSE, 0);
	gtk_widget_show(use_stepper);

	gtk_container_add(GTK_CONTAINER(options_frame), options_vbox);
	gtk_widget_show(options_vbox);
	gtk_box_pack_start(GTK_BOX(vbox), options_frame, TRUE, TRUE, 0);
	gtk_widget_show(options_frame);
	bbox = gtk_hbutton_box_new();
	gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
	gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
	gtk_box_pack_start(GTK_BOX(gvbox), bbox, FALSE, FALSE, 0);
	generallabel = gtk_label_new("General");
	gtk_widget_show(generallabel);
	gtk_widget_show(vbox);
	gtk_notebook_append_page(GTK_NOTEBOOK(notebook1), vbox, generallabel);
	/* Sensitivity Tab Notebook */
	svbox = gtk_vbox_new(FALSE, 5);
	/* Lock frame */
	lock_frame = gtk_frame_new("All chanells");
	gtk_container_set_border_width(GTK_CONTAINER(lock_frame), 5);
	lock_vbox = gtk_vbox_new(FALSE, 5);
	gtk_container_set_border_width(GTK_CONTAINER(lock_vbox), 5);
	gtk_container_add(GTK_CONTAINER(lock_frame), lock_vbox);
	gtk_widget_show(lock_vbox);
	gtk_box_pack_start(GTK_BOX(svbox), lock_frame, TRUE, TRUE, 0);
	gtk_widget_show(lock_frame);
	lockchan = (GtkWidget *)gtk_adjustment_new(oldmoveall, 1.0,
		(float)(MAX_SENSE + 1), 1.0, 3.0, 1.0);
	gtk_signal_connect(GTK_OBJECT(lockchan), "value_changed",
		GTK_SIGNAL_FUNC(conf_moveall), &configure_win);
	lockscale = gtk_hscale_new(GTK_ADJUSTMENT(lockchan));
	gtk_scale_set_digits(GTK_SCALE(lockscale), 0);
	gtk_scale_set_draw_value(GTK_SCALE(lockscale), TRUE);
	gtk_scale_set_value_pos(GTK_SCALE(lockscale), GTK_POS_BOTTOM);
/*
	tousefirst = gtk_check_button_new_with_label(
		"Use first channel as a template");
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lockscale),
		cfg.tousefirst);
*/
	gtk_box_pack_start(GTK_BOX(lock_vbox), lockscale, FALSE, FALSE, 0);
	gtk_widget_show(lockscale);
	/* Channels frame */
	chanells_frame = gtk_frame_new("Chanells:");
	gtk_container_set_border_width(GTK_CONTAINER(chanells_frame), 5);
	chanells_vbox = gtk_vbox_new(FALSE, 5);
	gtk_container_set_border_width(GTK_CONTAINER(chanells_vbox), 5);
	for (ii = 0; ii < NUM_BANDS; ii++)
	{
		sprintf(mytext, "%d", ii + 1);
		panhbox[ii] = gtk_hbox_new(FALSE, 5);
		gtk_box_pack_start(GTK_BOX(chanells_vbox), panhbox[ii],
			FALSE, FALSE, 0);
		panlabel[ii] = gtk_label_new(mytext);
		gtk_box_pack_start(GTK_BOX(panhbox[ii]),
			panlabel[ii], FALSE, FALSE, 0);
		gtk_widget_show(panlabel[ii]);
		/* curr, min, max, c?, dun, c? */
		pansep_adj[ii] = (GtkWidget *)gtk_adjustment_new(
			lcfg.chsense[ii], 1.0, (float)(MAX_SENSE + 1), 1.0,
			3.0, 1.0);
		pansep_hscale[ii] = gtk_hscale_new(GTK_ADJUSTMENT(
			pansep_adj[ii]));
		gtk_scale_set_digits(GTK_SCALE(pansep_hscale[ii]), 0);
		gtk_scale_set_draw_value(GTK_SCALE(pansep_hscale[ii]), TRUE);
		gtk_scale_set_value_pos(GTK_SCALE(pansep_hscale[ii]),
			GTK_POS_BOTTOM);
		gtk_widget_show(pansep_hscale[ii]);
		gtk_box_pack_start(GTK_BOX(panhbox[ii]), pansep_hscale[ii],
			TRUE, TRUE, 0);
		gtk_signal_connect(GTK_OBJECT(pansep_adj[ii]),
			"value_changed", GTK_SIGNAL_FUNC(conf_apply),
			&configure_win);
		gtk_widget_show(panhbox[ii]);
 	}
	gtk_container_add(GTK_CONTAINER(chanells_frame), chanells_vbox);
	gtk_widget_show(chanells_vbox);
	gtk_box_pack_start(GTK_BOX(svbox), chanells_frame, TRUE, TRUE, 0);
	gtk_widget_show(chanells_frame);
	senselabel = gtk_label_new("Sensitivity");
	gtk_widget_show(senselabel);
	gtk_widget_show(svbox);
	gtk_notebook_append_page(GTK_NOTEBOOK(notebook1), svbox, senselabel);
	/* General OK and Cancel buttons */
	ok = gtk_button_new_with_label("Ok");
	gtk_signal_connect_object(GTK_OBJECT(ok), "clicked",
		GTK_SIGNAL_FUNC(conf_ok), NULL);
	GTK_WIDGET_SET_FLAGS(ok, GTK_CAN_DEFAULT);
	gtk_box_pack_start(GTK_BOX(bbox), ok, TRUE, TRUE, 0);
	gtk_widget_show(ok);
	cancel = gtk_button_new_with_label("Cancel");
	gtk_signal_connect_object(GTK_OBJECT(cancel), "clicked",
		GTK_SIGNAL_FUNC(conf_cancel), NULL);
	GTK_WIDGET_SET_FLAGS(cancel, GTK_CAN_DEFAULT);
	gtk_box_pack_start(GTK_BOX(bbox), cancel, TRUE, TRUE, 0);
	gtk_widget_show(cancel);
	gtk_widget_show(bbox);
	gtk_container_add(GTK_CONTAINER(configure_win), gvbox);
	gtk_widget_show(gvbox);
	gtk_widget_show(configure_win);
	gtk_widget_grab_default(ok);

}

static void about(void)
{
	static GtkWidget *dialog;

	dialog = audacious_info_dialog (("About LPTLEDS Plugin"),
					("LPT Leds Visualization Plugin for Audacious\n"
					"based on xplsisnjasp XMMS plugin http://www.na.linux.hr/projects/xplsisnjasp/ \n"
					"Coded for Audacious Aleksey Makchno <silentlexx@gmail.com> \n"
					"Coded origin Xplsisnjasp  by Vlatko Kosturjak <kost@iname.com>\n"
					"and Robert Avilov <ravilov@linux.hr>.\n"
					"http://code.google.com/p/lptleds/\n"),
					("OK"), TRUE, NULL, NULL);

gtk_signal_connect(GTK_OBJECT(dialog), "destroy",
			   GTK_SIGNAL_FUNC(gtk_widget_destroyed), &dialog);

}
